home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / programs / sound / delitracker_v2.01 / developer / developer.dok < prev    next >
Text File  |  1995-02-13  |  36KB  |  829 lines

  1.  
  2.  
  3.                  $VER: Developer.dok V2.00 (13.04.1994)
  4.                    Copyright 1994 by Delirium Softdesign
  5.                       (Peter Kunath and Frank Riffel)
  6.  
  7.                   DeliTracker Development Documentation
  8.  
  9.  
  10.   1.ÜBERBLICK
  11.  
  12.   2.PLAYER
  13.    2.1 Normale Player
  14.    2.2 Custom Module
  15.    2.3 Interrupts
  16.  
  17.   3.GENIES
  18.    3.1 Generic Kind
  19.    3.2 Converter
  20.    3.3 Decruncher
  21.    3.4 NotePlayer
  22.  
  23.   4.TAGS
  24.  
  25.   5.DELITRACKER SUPPORT FUNKTIONEN
  26.  
  27.  
  28.   1.ÜBERBLICK
  29.  
  30.   DeliTracker kann mit externen Programmodulen erweitert werden. Diese
  31.   sehen vom DOS aus betrachtet genauso aus wie normale Objectfiles, mit
  32.   dem Unterschied allerdings, daß sie am Anfang des ersten Hunks eine
  33.   spezielle Struktur besitzen. Wenn DeliTracker ein solches Programmodul
  34.   nachlädt, wertet er diese Struktur aus. Sie besteht aus drei Teilen:
  35.   Einem Longword mit Code, zwei Longwords als Identifier und als letztes
  36.   einem Pointer auf ein Tagarray. Das erste Longword enthält normalerweise
  37.   moveq #-1,d0 gefolgt von einem rts Befehl. Dies soll einen Absturz
  38.   verhindern, wenn ein Player oder Genie irrtümlich vom Benutzer gestartet
  39.   wird. Um ein Programm zu erzeugen, das auch ohne DeliTracker lauffähig
  40.   ist, muß in das erste Longword in einen bra.w geändert werden, der dann
  41.   den eigentlichen Startupcode anspringt. Um die charakteristische Struktur
  42.   zu erzeugen sollte das PLAYERHEADER Macro aus 'deliplayer.i' verwendet
  43.   werden. Es hat zwei Parameter: einen Pointer auf ein Tagarray und
  44.   optional einen Pointer auf den Startupcode.
  45.  
  46.     PLAYERHEADER <tagarray>,[startup]
  47.  
  48.         tagarray        Pointer auf ein Tag Array, das mit TAG_DONE
  49.                         abgeschlossen sein muß.
  50.         startup         Pointer auf einen optionalen Startupcode. Nur
  51.                         notwendig, wenn das Programmodul auch ohne
  52.                         DeliTracker lauffähig sein soll.
  53.                         Bemerkung: Wenn der Startupcode angesprungen
  54.                         wird, muß die gesamte Initialisierung etc. ohne
  55.                         DeliTracker durchgeführt werden. In den meisten
  56.                         Fällen macht die Startup Option wenig Sinn und
  57.                         wird deshalb auch kaum benutzt.
  58.  
  59.   Die Tagliste enthält dabei alle Informationen, die DeliTracker wissen
  60.   muß. Wir verwenden ein Tagarray deshalb, weil es sehr flexibel und leicht
  61.   erweiterbar ist. Zusätzlich können die externen Programmodule noch die
  62.   GlobalStructure sowie die eingebauten Supportfunktionen benutzen. Im
  63.   Moment unterscheidet DeliTracker zwei verschiedene Typen von externen
  64.   Programmodulen:
  65.  
  66.         1) Player, um Module zu identifizieren und zu spielen
  67.  
  68.         2) Genies können viele andere Dinge machen. Unter anderem Module
  69.            konvertieren, Dateien entpacken oder Informationen anzeigen.
  70.  
  71.   Beide Arten können synchron oder asynchron laufen. Unter synchron
  72.   versteht man, daß der Player oder das Genie nicht als eigener Prozess
  73.   läuft. DeliTracker benutzt in diesem Fall echte Funktionsaufrufe (jsr)
  74.   zur Kommunikation. Im asynchronen Modus startet DeliTracker den Player
  75.   oder das Genie als eigenen Prozess und verwendet dann Messages um
  76.   Funktionen der externen Programmodule aufzurufen. Im allgemeinen laufen
  77.   Genies asynchron und Player synchron. Wenn ein Player oder ein Genie
  78.   asynchron läuft, dann muss man es durch Senden eines CTRL-C Signals an
  79.   den Prozeß beenden können. Offensichtlich sind DeliPlayer und DeliGenies
  80.   also sehr ähnlich. Sie werden von DeliTracker auch ziemlich gleich
  81.   verwaltet, wenn auch in zwei verschiedenen Listen. Jedes externe
  82.   Programmodul bei dem ein DTP_CustomPlayer, DTP_Check1 oder DTP_Check2
  83.   Tag benutzt wird, ist ein Player. Der Rest sind Genies.
  84.  
  85.   Wenn eine GUI vorhanden ist, sollten normalerweise folgende Menüpunkte
  86.   zur Verfügung stehen:
  87.  
  88.         Project
  89.                 About      A ?  Kurzinformation über das Programmodul
  90.                 ==============
  91.                 Save Prefs A S  Speichern der aktuellen Einstellungen
  92.                 ==============
  93.                 Hide       A H  GUI verbergen
  94.                 ==============
  95.                 Quit       A Q  Genie beenden (ebenso wie CTRL-C)
  96.  
  97.         Settings
  98.                 Activate   A A  Aktiviert das Fenster beim Öffnen des GUI
  99.                 Popup      A P  Öffnet das GUI nach dem Laden
  100.                 ==============
  101.                 Other settings  Hier können je nach Bedarf weitere
  102.                 ··············  Einstellungen folgen.
  103.  
  104.   Ein paar Anmerkungen:
  105.  
  106.   Bevor man einen DeliPlayer schreibt, sollte man sich die migelieferten
  107.   Beispielsourcen genau durchlesen. Um einen besseren Überblick davon zu
  108.   bekommen, wann und in welcher Reihenfolge DeliTracker die Funktionen des
  109.   Players aufruft, kann man den 'Testplayer.s' Source benutzen. Wenn eine
  110.   Konfigurationsdatei abgespeichert werden kann, sollte sie nicht nach
  111.   ENV:, sondern in das DeliTracker Konfiguartionsverzeichnis abgespeichert
  112.   werden. Der Pfad des Konfiguartionsverzeichnisses kann steht in der ENV-
  113.   Vaiable 'DeliConfig'. Falls diese nicht vorhanden ist, sollte stattdessen
  114.   'PROGDIR:DeliConfig' zum Abspeichern benutzt werden. Ein Player sollte
  115.   außerdem den Zustand der LED (Lowpass-Filter) unbeeinflußt lassen, da im
  116.   Optionfenster eine entsprechende Funktion existiert. Wenn von DeliTracker
  117.   eine Funktion des Players aufgerufen wird (außer bei den Interrupt-
  118.   Funktionen DTP_Interrupt und DTP_NoteSignal), enthält das Register a5
  119.   einen Pointer auf die Globale Struktur (Base). Da DeliTracker vor Aufruf
  120.   einer Routine (außer bei DTP_Interrupt und DTP_NoteSignal) alle Register
  121.   sichert, dürfen diese verändert werden.
  122.  
  123.  
  124.   2.PLAYERS
  125.  
  126.   Es ist relativ einfach, eine Replayroutine an DeliTracker anzupassen.
  127.   Alles was Sie tun müssen ist ein wenig Interfacecode zu schreiben. Dies
  128.   ist im allgemeinen recht einfach, denn DeliTracker stellt ihnen viele
  129.   hilfreiche Routinen zur Verfügung. Um ein neues Soundsystem anzupassen,
  130.   benötigen Sie zum einen den Quellcode oder ein linkbares Objektfile der
  131.   Replayroutine, zum anderen sollten mindestens ca. 5 Module zum Testen der
  132.   Funktionstüchtigkeit des Players vorhanden sein. Ganz am Anfang eines
  133.   Players muß sie charakteristische Struktur stehen. DeliTracker unter-
  134.   scheidet dann zwei Arten von Playern: normale Player und Custom Module.
  135.  
  136.     2.1 Normale Player
  137.  
  138.     Normale Player identifizieren und spielen Module. Sie müssen immer eine
  139.     Check Routine besitzen. Der schematische Aufbau eines normalen Players
  140.     ist folgendermassen:
  141.  
  142.         { Playerheader  }       Kennzeichnet das Object als Player.
  143.         { TagArray      }       Beschreibung, was der Player kann.
  144.         { Interfacecode }       Playername/Registerumsetzung/Checkcode u.ä.
  145.         { Replaycode    }       Eigentlicher Musikabspielcode.
  146.         { evtl. Daten   }       und Daten
  147.  
  148.     Damit der Player die einzelnen Module unterscheiden kann, befindet sich
  149.     in jedem Player eine Erkennungsroutine, die auf ein zugehöriges Modul
  150.     testet und DeliTracker mitteilt, ob der Player dieses Modul spielen
  151.     kann oder nicht. Diese Routine prüft auf Stellen im Modul, die bei allen
  152.     Modulen eines Formats gleich sind. So z.B. auf 'M.K.' bei Offset $438
  153.     in ProTracker-Modulen. Nur auf einige wenige Sprungbefehle zu Prüfen
  154.     reicht im allgemeinen nicht aus, da viele Modulformate mit eingebauter
  155.     Abspielroutine Sprungbefehle am Anfang haben und der Player möglicher-
  156.     weise das falsche Modul erkennen könnte, was in den meisten Fällen zum
  157.     Absturz führt! Deshalb sollte die Check Routine auch eingehend getestet
  158.     werden. Es gibt zwei Typen von Check Funktionen, genau eine davon muß
  159.     der Player verwenden.
  160.  
  161.     a) DTP_Check1: Diese Check Funktion wird aufgerufen, wenn DeliTracker
  162.     1K des Files geladen hat. Der Vorteil ist daß sich auch Player
  163.     realisieren lassen, die das Modul selbst nachladen. Der Nachteil ist,
  164.     daß der Player dann nicht von den Entpackroutinen in DeliTracker
  165.     profitiert. Meistens ist es deshalb schwerer, einen solchen Player zu
  166.     schreiben. Man sollte diesen Typ nur für Härtefälle verwenden, z.B.
  167.     wenn das Modul vom Player selbst geladen werden muß.
  168.  
  169.     b) DTP_Check2: Diese Check Routine wird aufgerufen, wenn das Modul
  170.     geladen und ggf. entpackt ist. Da ein Player mit dieser Check Funktion
  171.     im allgemeinen leichter zu schreiben ist, sollte im Normalfall diese
  172.     Check Routine verwendet werden.
  173.  
  174.     Egal welche Checkfunktion verwendet wird, wenn der Player das Modul
  175.     erkannt hat, muß er in d0.l=0 zurückliefern, wenn nicht d0.l<>0.
  176.  
  177.  
  178.     2.2 Custom Module
  179.  
  180.     Custom Module sind keine Module im herkömmlichen Sinn, sondern
  181.     besondere Player, die ein Modul beinhalten. Sie haben auch keine
  182.     Check Funktion, stattdessen muß der DTP_CustomPlayer Tag verwendet
  183.     werden. Mit diesem Interface kann man auch die ausgefallensten
  184.     Moduleformate an DeliTracker anpassen. Sollten jedoch mehrere Module
  185.     dieses Typs existieren, ist es in jedem Fall ratsam, einen richtigen
  186.     Player zu schreiben.
  187.  
  188.         { Playerheader  }       Kennzeichnet das Object als Player.
  189.         { TagArray      }       Beschreibung, was der Player kann.
  190.         { Interfacecode }       Routinen zur Registerumsetzung u.ä.
  191.         { Replaycode    }       Eigentlicher Musikabspielcode.
  192.         { evtl. Daten   }       und Daten
  193.         { SOUND DATEN   }       Das eigentliche Modul
  194.  
  195.  
  196.     2.3 Interrupts
  197.  
  198.     Hier gibt es eine Einteilung in zwei verschiedene Typen.
  199.  
  200.     a) Player die den DeliTracker Interrupt verwenden
  201.  
  202.      Vorteil:  Der Player ist vom Videomodus unabhängig.
  203.                Besitzt automatisch die Faster/Slower Funktion.
  204.                Kein Aufwand für den Interrupt (Code + Interruptstruktur).
  205.                Automatisch kompatibel zum serial.device.
  206.      Nachteil: Der Interrupt kommt nicht synchron zum VBlank. (Dies führt
  207.                nur in den seltensten Fällen zu Problemen.)
  208.  
  209.     b) Player die ihren eigenen Interrupt erzeugen.
  210.  
  211.      Vorteil:  Es können andere Interruptquellen benutzt werden
  212.                (z.B. AudioIRQ).
  213.      Nachteil: Erhöhter Aufwand, bei VBlank nicht mehr unabhängig vom
  214.                Videomodus.
  215.  
  216.     Wenn ein eigener Timerinterrupt verwendet wird, sollte die CIAB
  217.     (wg. OS2.0) und die entsprechenden Resourcefunktionen verwendet werden.
  218.     Außerdem ist es sehr sinnvoll die Replayroutine nicht direkt im CIA-B
  219.     TimerInterrupt laufen zu lassen, sondern im Timerinterrupt einen
  220.     Soft-Interrupt mittels Cause() zu generieren. In diesem SoftInt kann
  221.     man dann die eigentliche Replayroutine ablaufen lassen. Das hat den
  222.     Vorteil, daß man wesentlich kompatibler zum serial.device ist. Dies
  223.     liegt daran, daß SoftInt eine niedrigere Priorität als der der RBF
  224.     (Read Buffer Full) Interrupt hat d.h. erst wird der serielle Port
  225.     bedient, dann erst die Replayroutine. Es wird davor gewarnt, direkt
  226.     in die Interruptvektoren zu schreiben! Vom Betriebssystem werden dafür
  227.     die Funktionen AddIntServer() und SetIntVector() zur Verfügung
  228.     gestellt.
  229.  
  230.  
  231.   3.GENIES
  232.  
  233.   Die Funktionalität von DeliTracker kann mit Hilfe von Genies auf viele
  234.   verschiedene Arten erweitert werden. Im Moment existieren vier
  235.   grundsätzlich verschiedene Einsatzgebiete für Genies: die Ausgabe von
  236.   Noten (nicht zu verwechseln mit Playern), das Entpacken und Konvertieren
  237.   von Modulen und schließlich das Analysieren des aktuellen Moduls.
  238.  
  239.     3.1 Generic Kind
  240.  
  241.     Diese Art von Genies ist nicht auf spezielle Aufgaben beschrängt. Es
  242.     kann z.B. diverse Informationen über das Modul anzeigen. Natürlich
  243.     darf weder das Modul noch die Globale Struktur zur Gewinnung dieser
  244.     Informationen verändert werden. Überlicherweise benutzt dieser Genie-
  245.     Typ DTP_InitPlay/DTP_EndPlay um zu erfahren, wenn ein neues Modul
  246.     gespielt wird, zusätzlich evtl. auch noch DTP_StartInt/DTP_StopInt.
  247.  
  248.     3.2 Converter
  249.  
  250.     Diese Genies verändern ein Modul. So kann man z.B. das Format des
  251.     Moduls oder seine Länge ändern. Für diese Aufgabe gibt es einen
  252.     speziellen Tag, nämlich DTP_Convert. Er enthält die Adresse der
  253.     Convert-Funktion.
  254.  
  255.     3.3 Decruncher
  256.  
  257.     Diese Art von Genies erweitert die dtg_LoadFile() Funktion von
  258.     DeliTracker. Da sich dieses Interface noch ändern wird, ist es im
  259.     Moment noch nicht dokumentiert.
  260.  
  261.     3.4 Noteplayer
  262.  
  263.     Diese Genies haben die Aufgabe, 'Noten' ggf. zu konvertieren und sie
  264.     auf der jeweiligen Audiohardware auszugeben. Dieses Interface ist zur
  265.     Zeit noch Änderungen unterworfen und deshalb noch nicht dokumentiert.
  266.  
  267.  
  268.   4. TAGS
  269.  
  270.   Außer den SystemTags (TAG_DONE, TAG_IGNORE, TAG_MORE, TAG_SKIP) dürfen
  271.   folgende Tags verwendet werden:
  272.  
  273.   DTP_CustomPlayer (BOOL) - dieser Tag deklariert einen Player als
  274.                 Customplayer.
  275.                 Bei Verwendung dieses Tags sind folgende Tags dann
  276.                 bedeutungslos:  DTP_PlayerVersion
  277.                                 DTP_PlayerName
  278.                                 DTP_Creator
  279.                                 DTP_Check1
  280.                                 DTP_Check2
  281.                                 DTP_ExtLoad
  282.                                 DTP_Config
  283.                                 DTP_UserConfig
  284.  
  285.   DTP_RequestDTVersion (WORD) - damit kann man sicherstellen, daß
  286.                 mindestens eine bestimmte Version von DeliTracker
  287.                 vorhanden ist. Dieser Tag muß angegeben werden, wenn
  288.                 bei den DeliTrackerGlobals neue Funktionspointer
  289.                 hinzugekommen sind und diese vom Player benutzt werden.
  290.                 ti_Data ist dabei die Playerrevision.
  291.  
  292.   DTP_RequestKickVersion (ULONG) - wenn dieser Tag angegeben ist, wird
  293.                 der Player nur noch von von DeliTracker geladen, wenn
  294.                 mindestens die angeforderte Kickstart Version vorhanden
  295.                 ist.
  296.  
  297.   DTP_PlayerVersion (WORD) - Tag, der die Versionsnummer (high word) und
  298.                 die Revisionsnummer (low word) des Players enthält. Bei
  299.                 zwei Playern mit dem gleichen Playernamen wird derjenige
  300.                 mit der größeren Revisionsnummer geladen.
  301.  
  302.   DTP_PlayerName (STRPTR) - ti_Data enthält den Pointer auf den Namen des
  303.                 Players. Dieser String kann zwar beliebig lang sein aber
  304.                 zur Zeit werden nur die ersten 24 Zeichen angezeigt. Dieser
  305.                 Tag muß existieren!
  306.  
  307.   DTP_Creator (STRPTR) - Pointer auf den Namen des Autors. Dieser wird im
  308.                 Playerfenster im Playerinfofeld angezeigt. Der String
  309.                 kann $A als Zeilenumbruch enthalten.
  310.  
  311.   DTP_Check1 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
  312.                 aufgerufen wird, wenn 1024 Bytes des Moduls geladen sind.
  313.                 Wird das Modul erkannt, liefert sie d0=0, ansonsten d0<>0.
  314.  
  315.   DTP_Check2 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
  316.                 aufgerufen wird, wenn das komplette Modul geladen und evtl.
  317.                 entpackt ist. Wird das Modul erkannt, liefert sie d0=0,
  318.                 ansonsten d0<>0.
  319.  
  320.   DTP_ExtLoad (FPTR) - Pointer auf eine optionale Laderoutine für Module.
  321.                 Ist kein Fehler aufgetreten, wird d0=0 zurückgegeben, sonst
  322.                 d0<>0. Hinweis: Achten Sie darauf, daß im Fehlerfall alle
  323.                 allocierten Ressourcen (Memory, Locks, ...) wieder
  324.                 freigegeben werden, da dann keine weiteren Playerfunktionen
  325.                 mehr angesprungen werden.
  326.  
  327.   DTP_Interrupt (FPTR) - Pointer auf eine Interruptroutine, die mittels
  328.                 eines Timerinterrupts standardmäßig alle 1/50 sec
  329.                 aufgerufen wird. Dies ist die Standardmethode, um mit der
  330.                 richtigen Abspielgeschwindigkeit im PAL/NTSC/Productivity
  331.                 Videomodus zu spielen. Wenn keine DTP_Faster/DTP_Slower
  332.                 Tags angegeben sind, übernimmt DeliTracker dies durch
  333.                 Verändern der Interruptfrequenz. Dieser Tag kann auch nicht
  334.                 existieren, dann müssen aber DTP_StartInt/DTP_StopInt
  335.                 vorhanden sein !
  336.  
  337.   DTP_Stop (FPTR) - Pointer auf eine optionale Stoproutine. Wenn dieser Tag
  338.                 nicht vorhanden ist, verfährt DeliTracker folgendermaßen:
  339.                         Interrupt stoppen (DTP_StopInt)
  340.                         Sound Cleanup (DTP_EndSnd)
  341.                         Song initialisieren (DTP_InitSnd)
  342.                 Ansonsten hat diese Routine die Aufgabe, einen evtl.
  343.                 spielenden Song anzuhalten und so zu initialisieren, daß
  344.                 dieser beim nächsten Starten des Interrupts von Anfang an
  345.                 zu spielen beginnt.
  346.  
  347.   DTP_Config (FPTR) - Pointer auf eine optionale Initialisierungsroutine.
  348.                 Diese wird nur einmal unmittelbar nach dem Laden des
  349.                 Players aufgerufen. Mögliche Anwendungen: Laden einer
  350.                 playerspezifischen Konfigurationsdatei. Ist kein Fehler
  351.                 aufgetreten, muss d0=0 zurückgegeben werden, sonst
  352.                 d0<>0. Hinweis: Im Fehlerfall wird der Player von
  353.                 DeliTracker wieder entfernt!
  354.  
  355.   DTP_UserConfig (FPTR) - Pointer auf eine optionale Initialisierungs-
  356.                 routine. Diese wird nur dann aufgerufen, wenn der User den
  357.                 Player im Setupfenster anwählt und das 'Config' Gadget
  358.                 drückt. Mögliche Anwendungen: Öffnen eines Fensters zum
  359.                 Setzen weiterer Optionen wie z.B. Instrumentenpfad und
  360.                 Abspeichern einer playerspezifischen Konfigurationsdatei.
  361.  
  362.   DTP_SubSongRange (FPTR) - Überholt, bitte DTP_NewSubSongRange benützen!
  363.                 Dieser Tag sollte angegeben werden, wenn der Player
  364.                 MultiModule unterstützt. ti_Data zeigt dabei auf eine
  365.                 Routine, die als Returnwert in d0 die minimale und
  366.                 in d1 die maximale Subsongnummer zurückgeben muß.
  367.                 Hinweis: Wenn möglich sollte dieser Tag (evtl. zusammen
  368.                 mit DTP_SubSongTest) anstelle von DTP_NextSong/DTP_PrevSong
  369.                 verwendet werden.
  370.  
  371.   DTP_InitPlayer (FPTR) - Pointer auf eine optionale Initialsierungs-
  372.                 routine, die aufgerufen wird, wenn ein Modul erfolgreich
  373.                 geladen wurde. Tritt kein Fehler auf, liefert sie d0=0,
  374.                 ansonsten d0<>0. Hier muß die Allocation der Audiokanäle
  375.                 stattfinden! (DeliTracker stellt dafür eine eigene Routine
  376.                 zur Verfügung) Falls der Player Multi-Module unterstützt,
  377.                 muß hier dtg_SndNum(a5) auf die erste Subsongnummer gesetzt
  378.                 werden. Falls eine Routine für DTP_SubSongRange existiert,
  379.                 macht DeliTracker das automatisch (d.h. die Initialisierung
  380.                 von dtg_SndNum(a5) kann weggelassen werden).
  381.  
  382.   DTP_EndPlayer (FPTR) - Pointer auf eine optionale Cleanuproutine, die
  383.                 aufgerufen wird, wenn das Modul aus dem Speicher entfernt
  384.                 wird. Hier muß die Freigabe der Audiokanäle stattfinden!
  385.                 (DeliTracker stellt dafür eine eigene Routine zur
  386.                 Verfügung)
  387.  
  388.   DTP_InitSound (FPTR) - Pointer auf eine optionale Initialsierungsroutine.
  389.                 Diese muß das Modul initialisieren, so daß beim Starten des
  390.                 Interrupts der Song von Anfang an zu spielen beginnt.
  391.  
  392.   DTP_EndSound (FPTR) - Pointer auf eine optionale Cleanuproutine. Diese
  393.                 kann z.B. die Lautstärkeregister und die Audio-DMA
  394.                 rücksetzen.
  395.  
  396.   DTP_StartInt (FPTR) - Pointer auf eine Initialsierungsroutine, die
  397.                 existieren muß, wenn DTP_Interrupt nicht vorhanden ist.
  398.                 In diesem Fall muß hier der Sound gestartet werden.
  399.  
  400.   DTP_StopInt (FPTR) - Pointer auf eine Cleanuproutine, die existieren muß,
  401.                 wenn DTP_Interrupt nicht vorhanden ist. In diesem Fall muß
  402.                 hier der Sound gestoppt werden.
  403.  
  404.   DTP_Volume (FPTR) - Pointer auf eine Funktion, welche die Lautstärke neu
  405.                 setzt. Die Funktion wird aufgerufen, wenn die Volume neu
  406.                 gesetzt wird (Slider, ARexx) und beim Initialisieren des
  407.                 Moduls vor DTP_InitSnd. Die Mastervolume steht in
  408.                 dtg_SndVol(a5). Die Mastervolume ist dabei der maximale
  409.                 Volumewert. Die effektive Volume errechnet sich also
  410.                 durch: VOL_eff = (( dtg_Volume(a5) * modulevolume )>>6)
  411.                 Näheres siehe Beispielsourcen.
  412.  
  413.   DTP_Balance (FPTR) - Pointer auf eine Funktion, welche die Balance neu
  414.                 setzt. Die Funktion wird aufgerufen, wenn die Balance neu
  415.                 gesetzt wird (Slider, ARexx) und beim Initialisieren des
  416.                 Moduls vor DTP_InitSnd. Die Balance für die linken Kanäle
  417.                 steht in dtg_SndLBal(a5), für die rechten Kanäle in
  418.                 dtg_SndRBal(a5). Hinweis: Alle Player die Balance unterstützen
  419.                 können auch Volume! Man verwendet dann die gleiche Routine
  420.                 zum Setzen der Volume&Balance. Die linke Volume errechnet
  421.                 sich wie folgt: (( dtg_Volume(a5) * dtg_SndLBal(a5) )>>6)
  422.                 Entsprechendes gilt für rechts.
  423.  
  424.   DTP_Faster (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
  425.                 beschleunigt.
  426.  
  427.   DTP_Slower (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
  428.                 verlangsamt.
  429.  
  430.   DTP_NextPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
  431.                 um eins erhöht.
  432.  
  433.   DTP_PrevPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
  434.                 um eins erniedrigt.
  435.  
  436.   DTP_NextSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
  437.                 den nächsten Subsong setzt und diesen spielt.
  438.                 (Falls vorhanden)
  439.  
  440.   DTP_PrevSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
  441.                 den vorhergehenden Subsong setzt und diesen spielt.
  442.                 (Falls vorhanden)
  443.  
  444.   ;--- tags in revision 14 or higher (distributed as Release 1.35) ---
  445.  
  446.   DTP_SubSongTest (FPTR) - Dieser Tag wird nur ausgewertet, wenn schon der
  447.                 Tag DTP_SubSongRange angegeben wurde. ti_Data zeigt dabei
  448.                 auf eine Routine, die als Returnwert in d0 einen Boolschen
  449.                 Wert zurückliefert. Dieser gibt an, ob der SubSong mit
  450.                 Nummer dtg_SndNum(a5) gültig ist (d0=0) oder nicht (d0<>0).
  451.                 Dieser Tag ist nur bei den Playern nötig, bei denen nicht
  452.                 jeder SubSong (innerhalb der durch DTP_SubSongRange
  453.                 festgelegten Grenzen) benutzt ist.
  454.  
  455.   ;--- tags in revision 16 or higher (distributed as Release 2.00) ---
  456.  
  457.   DTP_NewSubSongRange (FPTR) - erweiterter Ersatz für DTP_SubSongRange.
  458.                 Dieser Tag sollte angegeben werden, wenn der Player
  459.                 MultiModule unterstützt. ti_Data zeigt dabei auf eine
  460.                 Funktion, die als Result einen Pointer auf ein Array
  461.                 mit drei WORDs zurückliefert: Das erste Word enthält
  462.                 die Nummer des Subsongs, der als erstes gespielt werden
  463.                 soll. Das zweite enthält die minimale und das dritte die
  464.                 maximale Subsong Nummer. In den meisten Fällen ist das
  465.                 erste und das zweite WORD identisch.
  466.  
  467.   DTP_DeliBase (APTR) - die Adresse eines Pointers, wo DeliTracker einen
  468.                 Pointer auf die DeliGlobals ablegt.
  469.  
  470.   DTP_Flags (ULONG) - enthält verschiedene Flags.
  471.                 Derzeit sind folgende Flags definiert:
  472.                 PLYF_CUSTOM     - der Player ist ein Customplayer
  473.                 PLYF_SONGEND    - dieser Player unterstützt Songend
  474.  
  475.   DTP_CheckLen (ULONG) - Länge des Check Codes. Dieser Tag darf nur benutzt
  476.                 werden, wenn der Checkcode PC-relativ und reentrant ist!
  477.                 Wenn der Tag benutzt wird, lagert DeliTracker den Player in
  478.                 LowMem-Situationen aus.
  479.  
  480.   DTP_Description (APTR) - Pointer auf einen String mit einer Beschreibung,
  481.                 was der Player bzw. das Genie tut und welche besonderen
  482.                 Fähigkeiten es hat. Dieser String kann $A als Zeilenumbruch
  483.                 enthalten.
  484.  
  485.   DTP_Decrunch (FPTR) - private, still under development!
  486.  
  487.   DTP_Convert (FPTR) - Pointer auf eine Routine zum Konvertieren eines
  488.                 Moduls. Diese Routine wird aufgerufen, wenn das Modul
  489.                 geladen und ggf. entpackt ist. Sie dient dazu, das Modul
  490.                 in ein neues Format umzukonvertieren. Die Konvertier-
  491.                 Routine funktioniert üblicherweise folgendermassen:
  492.                         1) Ausgangs-Format erkennen
  493.                         2) Speicher für Ziel-Format mit dtg_AllocListData()
  494.                            belegen
  495.                         3) Das Modul vom Ausgangsformat ins Zielformat
  496.                            konverieren
  497.                 Diese Routine muß NULL zurückliefern, wenn das Modul
  498.                 erfolgreich konvertiert wurde (success), ansonsten -1
  499.                 (error). Auf gar keinen Fall darf das Ausgangs-Modul von
  500.                 der Konvertier-Funktion verändert werden!
  501.                 Bemerkung: für temporäre Speicher-Allocationen sollte man
  502.                 die entsprechenden Exec-Funktionen benutzen, der Speicher
  503.                 für das Ziel-Modul muß aber in jedem Fall mit der Support
  504.                 Funktion dtg_AllocListData() belegt werden!
  505.  
  506.   DTP_NotePlayer (APTR) - private, still under development!
  507.  
  508.   DTP_NoteStruct (APTR) - private, still under development!
  509.  
  510.   DTP_NoteInfo (APTR) - private, still under development!
  511.  
  512.   DTP_NoteSignal (FPTR) - private, still under development!
  513.  
  514.   DTP_Process (FPTR) - Pointer auf einen Code, der als Prozess gestartet
  515.                 werden soll. Wenn dieser Tag verwendet wird, startet
  516.                 DeliTracker den Player bzw. das Genie als eigenen Prozess.
  517.  
  518.   DTP_Priority (BYTE) -  Priorität des zu startenden Prozesses. Nur in
  519.                 Verbindung mit DTP_Process sinnvoll.
  520.  
  521.   DTP_StackSize (ULONG) - Stack-Größe des zu startenden Prozesses. Nur in
  522.                 Verbindung mit DTP_Process sinnvoll.
  523.  
  524.   DTP_MsgPort (APTR) - Adresse eines Pointer, wo DeliTracker die Adresse
  525.                 des Ports ablegt, an den dann die Messages geschickt
  526.                 werden. Nur in Verbindung mit DTP_Process sinnvoll.
  527.  
  528.   DTP_Appear (FPTR) - Pointer auf eine Routine die die GUI des Players bzw.
  529.                 Genies öffnet/aktiviert. Als Returnwert muß der alte
  530.                 Windowzustand (<>0 wenn das Fenster auf war, ansonsten 0)
  531.                 zurückgeliefert werden. Bemerkung: Stellen Sie sicher, daß
  532.                 die GUI auf dem richtigen Screen geöffnet wird! (benützen
  533.                 Sie dazu die dtg_LockPubScreen() und dtg_UnLockPubScreen()
  534.                 Funktionen).
  535.  
  536.   DTP_Disappear (FPTR) - Pointer auf eine Routine, die die GUI schliesst.
  537.                 Diese Routine muss den alten Windowzustand (<>0 wenn das
  538.                 Fenster auf war, ansonsten 0) zurückgeliefern.
  539.  
  540.   DTP_ModuleName (APTR) - Adresse eines Pointers, der auf den tatsächlichen
  541.                 Namen des Moduls zeigt (dieser String muß mit NULL
  542.                 abgeschlossen sein). Dieser Tag ist nur für Player sinnvoll
  543.                 und wird nach InitPlay() ausgewertet.
  544.  
  545.   DTP_FormatName (APTR) - Adresse eines Pointers, der auf den Namen des
  546.                 urspünglichen Modulformats zeigt (dieser String muß mit
  547.                 NULL abgeschlossen sein). Dieser Tag ist nur für Genies
  548.                 sinnvoll und wird nach der Convert() Funktion ausgewertet.
  549.  
  550.  
  551.   5.DELITRACKER SUPPORT FUNKTIONEN
  552.  
  553.   DeliTracker stellt zur Erleichterung der Playeranpassung einige
  554.   Funktionen zur Verfügung. Eine Funktion wird wie folgt aufgerufen:
  555.  
  556.         move.l  dtg_XXX(a5),a0
  557.         jsr     (a0)
  558.  
  559.   Alle folgenden Funktionen außer dtg_SongEnd, dtg_SetTimer und
  560.   dtp_NotePlayer verwenden d0/d1/a0/a1 als Scratchregister. In a5 muß bei
  561.   allen Aufrufen (außer bei dtg_SongEnd, dtg_SetTimer und dtp_NotePlayer)
  562.   der Pointer auf die Base stehen. Derzeit existieren folgende Funktionen:
  563.  
  564.   dtg_GetListData
  565.  
  566.         SYNOPSIS
  567.                 memory size = dtg_GetListData(number)
  568.                 a0     d0                     d0.l
  569.  
  570.         FUNCTION
  571.                 Liefert Adresse und Länge eines mit LoadFile() geladenen
  572.                 Files.
  573.  
  574.         INPUTS
  575.                 number - Nummer eines Files beginnend mit 0 für das vom
  576.                          User selektierte File.
  577.  
  578.         RESULT
  579.                 memory - ein Pointer auf die Startadresse des Files im
  580.                          Speicher oder NULL im Fehlerfall.
  581.                 size - Länge des Files in Bytes bzw. 0 im Fehlerfall.
  582.  
  583.  
  584.   dtg_LoadFile
  585.  
  586.         SYNOPSIS
  587.                 success = dtg_LoadFile(name)
  588.  
  589.         FUNCTION
  590.                 Lädt und entpackt ggf. das angegebene File ins Chip-
  591.                 Memory. (Hinweis: diese Funktion ergänzt automatisch,
  592.                 falls das File mit dem angegebenen Namen nicht geöffnet
  593.                 werden konnte '.pp','.im' und '.xpk')
  594.  
  595.         INPUTS
  596.                 name - der Filename steht in einem internen Buffer (seine
  597.                        Adresse steht in dtg_PathArray)
  598.  
  599.         RESULT
  600.                 success - alles ok d0.l=0, sonst d0.l<>0.
  601.  
  602.  
  603.   dtg_CopyDir
  604.  
  605.         SYNOPSIS
  606.                 dtg_CopyDir()
  607.  
  608.         FUNCTION
  609.                 Kopiert das Directory des von User angewählten Files an das
  610.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  611.  
  612.  
  613.   dtg_CopyFile
  614.  
  615.         SYNOPSIS
  616.                 dtg_CopyFile()
  617.  
  618.         FUNCTION
  619.                 Kopiert den Filenamen des von User angewählten Files an das
  620.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  621.  
  622.  
  623.   dtg_CopyString
  624.  
  625.         SYNOPSIS
  626.                 dtg_CopyString(string)
  627.                                a0
  628.  
  629.         FUNCTION
  630.                 Kopiert den String, auf den das Register a0 zeigt, an das
  631.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  632.  
  633.         INPUTS
  634.                 string - der Pointer auf den anzuhängenden String steht
  635.                          in a0
  636.  
  637.  
  638.   dtg_AudioAlloc
  639.  
  640.         SYNOPSIS
  641.                 success = dtg_AudioAlloc()
  642.  
  643.         FUNCTION
  644.                 Belegt alle Audiokanäle.
  645.  
  646.         RESULT
  647.                 success - alles ok d0.l=0, sonst d0.l<>0.
  648.  
  649.  
  650.   dtg_AudioFree
  651.  
  652.         SYNOPSIS
  653.                 dtg_AudioFree()
  654.  
  655.         FUNCTION
  656.                 Gibt die mit dtg_AudioAlloc belegten Audiokanäle wieder
  657.                 frei.
  658.  
  659.  
  660.   dtg_StartInt
  661.  
  662.         SYNOPSIS
  663.                 dtg_StartInt()
  664.  
  665.         FUNCTION
  666.                 Startet den Soundinterrupt. (Falls er nicht schon läuft.)
  667.                 Falls DTP_Interrupt existiert, startet DeliTracker einen
  668.                 Timerinterrupt, ansonsten wird DTP_StartInt aufgerufen.
  669.  
  670.  
  671.   dtg_StopInt
  672.  
  673.         SYNOPSIS
  674.                 dtg_StopInt()
  675.  
  676.         FUNCTION
  677.                 Stoppt den Soundinterrupt. (Falls er nicht schon angehalten
  678.                 ist.) Falls DTP_Interrupt existiert, stoppt DeliTracker
  679.                 seinen Timerinterrupt, ansonsten wird DTP_StopInt
  680.                 aufgerufen.
  681.  
  682.  
  683.   dtg_SongEnd
  684.  
  685.         SYNOPSIS
  686.                 dtg_SongEnd()
  687.  
  688.         FUNCTION
  689.                 Signalisiert DeliTracker, daß das Modul einmal komplett
  690.                 gespielt wurde. Diese Funktion verändert keine Register
  691.                 und darf auch von Interrupts aufgerufen werden.
  692.  
  693.  
  694.   dtg_CutSuffix
  695.  
  696.         SYNOPSIS
  697.                 dtg_CutSuffix()
  698.  
  699.         FUNCTION
  700.                 Entfernt am Ende des Strings, auf den dtg_PathArray(a5)
  701.                 zeigt ggf. die Endung '.pp', '.im' oder '.xpk'
  702.  
  703.  
  704.   ;------ extensions in revision 14 (distributed as Release 1.34)
  705.  
  706.   dtg_SetTimer
  707.  
  708.         SYNOPSIS
  709.                 dtg_SetTimer()
  710.  
  711.         FUNCTION
  712.                 Programmiert den CIA-Timer mit dem Wert, der sich in
  713.                 dtg_Timer(a5) befindet. Diese Funktion verändert keine
  714.                 Register und darf auch von Interrupts aufgerufen werden.
  715.  
  716.  
  717.   ;------ extensions in revision 15 (distributed as Release 1.37)
  718.  
  719.   dtg_WaitAudioDMA
  720.  
  721.         SYNOPSIS
  722.                 dtg_WaitAudioDMA()
  723.  
  724.         FUNCTION
  725.                 Diese Funktion wartet eine bestimmte Zeit lang. Die
  726.                 Zeitspanne sollte für die Audio Hardware normalerweise
  727.                 groß genug sein, um neue Werte zu laden. Dieser Aufruf ist
  728.                 nur erlaubt, wenn der interne Timer-Interrupt benutzt wird.
  729.                 Er kann anstelle der üblichen dbra oder Rasterline
  730.                 Warteschleifen benutzt werden. Diese Funktion verändert
  731.                 keine Register.
  732.  
  733.         BUGS
  734.                 Wenn der Player auch Periods unterstützt, die viel größer
  735.                 als 1000 sind, wird evtl. nicht lange genug gewartet.
  736.  
  737.  
  738.   ;------ extensions in revision 16 (distributed as release 2.00)
  739.  
  740.   dtg_LockScreen
  741.  
  742.         SYNOPSIS
  743.                 screen = dtg_LockScreen()
  744.                 (d0)
  745.  
  746.         FUNCTION
  747.                 Lockt den Screen auf dem DeliTracker läuft (ist immer
  748.                 ein Pubscreen).
  749.  
  750.         RESULT
  751.                 Pointer auf den Screen in d0 oder NULL im Fehlerfall.
  752.  
  753.  
  754.   dtg_UnlockScreen
  755.  
  756.         SYNOPSIS
  757.                 dtg_UnlockScreen()
  758.  
  759.         FUNCTION
  760.                 Diese Function unlockt den Screen, auf dem DeliTracker
  761.                 läuft. Hinweis: diese Funktion keinesfalls öfters aufrufen
  762.                 als dtg_LockScreen()!).
  763.  
  764.  
  765.   dtg_NotePlayer
  766.  
  767.         SYNOPSIS
  768.                 dtg_NotePlayer()
  769.  
  770.  
  771.         FUNCTION
  772.                 Dieser Aufruf spielt die Noten, die in der aktuellen
  773.                 NoteStruct Struktur angegeben sind. Die Funktion darf
  774.                 nicht aufgerufen werden, wenn der aktive Player keine
  775.                 NotePlayer Structur hat.
  776.                 Hinweis: Dieser Aufruf sichert alle Register und darf
  777.                 sogar von Interrupts aufgerufen werden, solange das
  778.                 Interrupt Level 4 oder kleiner ist.
  779.  
  780.         INPUTS
  781.                 aktuelle NoteStruct.
  782.  
  783.  
  784.   dtg_AllocListData
  785.  
  786.         SYNOPSIS
  787.                 memory = dtg_AllocListData(byteSize,Flags)
  788.                 (d0)                      (d0.l) (d1.l)
  789.  
  790.  
  791.         FUNCTION
  792.                 Dies ist die Funktion, um Modul-spezifischen Speicher von
  793.                 Playern oder Genies aus zu belegen. Es gibt die Möglichkeit
  794.                 anzugeben, ob die Allocation im Chipmem oder Publicmem
  795.                 gemacht werden soll. Wenn die Allocation erfolgreich war,
  796.                 merkt DeliTracker sich den Memblock und man kann mit der
  797.                 Funktion dtg_GetListData() die Adresse und die Größe des
  798.                 Blocks erfahren.
  799.  
  800.  
  801.         INPUTS
  802.                 byteSize - Größe des gewünschten Blocks in Bytes.
  803.  
  804.                 Flags - die Flags werden an AllocMem() weitergereicht.
  805.  
  806.         RESULT
  807.                 Ein Pointer auf den allocierten Memoryblock wird in d0
  808.                 zurückgeliefert. Wenn nicht genug freier Speicher vorhanden
  809.                 ist, um die Anforderung zu erfüllen, wird Null
  810.                 zurückgegeben. Der Pointer muß auf jeden Fall getestet
  811.                 werden und darf nur benutzt werden, wenn er ungleich Null
  812.                 ist.
  813.  
  814.  
  815.   dtg_FreeListData
  816.  
  817.         SYNOPSIS
  818.                 dtg_FreeListData(memoryBlock)
  819.                                   (a1)
  820.  
  821.         FUNCTION
  822.                 Gibt einen Speicherblock frei, der mit AllocListData(),
  823.                 allociert wurde.
  824.  
  825.         INPUTS
  826.                 memoryBlock - Pointer auf den Speicherblock, darf auch
  827.                               NULL sein.
  828.  
  829.